package tj.warning.pull.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;
import tj.warning.pull.mapper.report2.Report2Mapper;
import tj.warning.pull.mapper.report3.Report3Mapper;
import tj.warning.pull.mapper.report3.SyncRecordMapper;
import tj.warning.pull.model.Repository;
import tj.warning.pull.model.SyncRecord;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BizService {

    @Value("${biz.tj.appKey}")
    private String appKey;

    @Value("${biz.tj.appSecret}")
    private String appSecret;

    @Value("${biz.tj.url1}")
    private String url1;

    @Value("${biz.tj.url2}")
    private String url2;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private Report3Mapper report3Mapper;
    @Resource
    private SyncRecordMapper syncRecordMapper;

    @Scheduled(fixedDelay = 30L, timeUnit = TimeUnit.MINUTES)
    public void syncTables() throws InterruptedException {
        List<String> jhListFromRemote = new ArrayList<>();
        List<String> jhListFormDb = new ArrayList<>();
        try {
            jhListFromRemote = getTablesFromRemote();
        } catch (Exception exception) {
            jhListFromRemote = getTablesFromDb();
        }
        jhListFormDb = getTablesFromDb();
        List<String> finalJhListFormDb = jhListFormDb;
        initRecordData();
        jhListFromRemote.forEach(jh -> {
            if (!finalJhListFormDb.contains(jh)) {
                this.report3Mapper.createTable(jh, System.currentTimeMillis());
                try {
                    Thread.sleep(5000L);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                long dataCounts = this.report3Mapper.dataCounts(jh, null, null);
                if (dataCounts > 0L) {
                    String maxTime = this.report3Mapper.selectMaxTimeFromDblink(jh);
                    this.syncRecordMapper.insert((new SyncRecord()).setId(UUID.randomUUID().toString()).setTableName(jh).setCollectTime(maxTime));
                    this.report3Mapper.syncHistoryData(jh, maxTime);
                } else {
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    String collectTime = formatter.format(LocalDateTime.now());
                    this.syncRecordMapper.insert((new SyncRecord()).setId(UUID.randomUUID().toString()).setTableName(jh).setCollectTime(collectTime));
                }
            }
        });
    }

    @Scheduled(fixedDelay = 30L, timeUnit = TimeUnit.SECONDS, initialDelay = 60L)
    public void syncData() {
        log.info("数据同步开始");
        long time = System.currentTimeMillis();
        List<SyncRecord> recordList = this.syncRecordMapper.selectList();
        recordList.parallelStream().forEach(record -> {
            String maxTime = this.report3Mapper.selectMaxTimeFromDblink(record.getTableName());
            if (!record.getCollectTime().equals(maxTime)) {
                record.setStartTime(record.getCollectTime()).setEndTime(maxTime);
                try {
                    long time3 = System.currentTimeMillis();
                    this.report3Mapper.syncCurrentData(record);
                    long time4 = System.currentTimeMillis();
                    log.info("{}-耗时：{}", record.getTableName(), Long.valueOf(time4 - time3));
                } catch (Exception ex) {
                    this.report3Mapper.dropTable(record.getTableName());
                    this.syncRecordMapper.deleteById(record.getId());
                    log.info("删除表{}", record.getTableName());
                    return;
                }
                this.syncRecordMapper.updateById(record.setCollectTime(maxTime));
            }
        });
        long time2 = System.currentTimeMillis();
        log.info("数据同步结束，耗时："+(time2-time));
    }

    public String getToken() {
        JSONObject result = (JSONObject)this.restTemplate.getForObject(this.url1 + "?appKey={1}&appSecret={2}", JSONObject.class, new Object[] { this.appKey, this.appSecret });
        String token = result.getString("token");
        Repository.token = token;
        return token;
    }

    public List<String> getTablesFromRemote() {
        if (Repository.token == null)
            getToken();
        List<String> list = new ArrayList<>();
        JSONObject result = (JSONObject)this.restTemplate.getForObject(this.url2 + "?token={1}", JSONObject.class, new Object[] { Repository.token });
        JSONArray data = result.getJSONArray("data");
        JSONArray jhJsonArray = data.getJSONObject(0).getJSONArray("datas");
        list = (List<String>)jhJsonArray.stream().map(it -> {
            String jh = JSONObject.parseObject(JSON.toJSONString(it)).getString("jh");
            jh = "LTD_" + jh.replace('-', '_').toUpperCase().trim();
            return "\"" + jh + "\"";
        }).collect(Collectors.toList());
        return list;
    }

    public List<String> getTablesFromDb() {
        List<String> jhList = this.report3Mapper.tableNames();
        jhList.remove("SYNC_RECORD");
        return (List<String>)jhList.stream().map(it -> "\"" + it + "\"").collect(Collectors.toList());
    }
    public void initRecordData() {
        List<String> tableNameList = getTablesFromDb();
        if (Repository.initRecord) {
            this.syncRecordMapper.truncate();
            Repository.initRecord = false;
            tableNameList.forEach(jh -> {
                String maxTime = this.report3Mapper.selectMaxTime(jh);
                if (maxTime == null) {
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    maxTime = formatter.format(LocalDateTime.now());
                }
                this.syncRecordMapper.insert((new SyncRecord()).setId(UUID.randomUUID().toString()).setTableName(jh).setCollectTime(maxTime));
            });
        } else {
            List<String> recordList = (List<String>)this.syncRecordMapper.selectList().stream().map(record -> record.getTableName()).collect(Collectors.toList());
            tableNameList.forEach(jh -> {
                if (!recordList.contains(jh)) {
                    String maxTime = this.report3Mapper.selectMaxTime(jh);
                    if (maxTime == null) {
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                        maxTime = formatter.format(LocalDateTime.now());
                    }
                    this.syncRecordMapper.insert((new SyncRecord()).setId(UUID.randomUUID().toString()).setTableName(jh).setCollectTime(maxTime));
                }
            });
        }
        log.info("初始化sync_record表结束");
    }
}










